﻿using System.Linq.Expressions;
using vm.Aspects.Diagnostics;

namespace vm.Aspects.Tests
{
    abstract class ExpressionMetadata
    {
        [Dump(0)]
        public object NodeType { get; set; }

        [Dump(-1)]
        public object Type { get; set; }

        [Dump(int.MinValue)]
        public object CanReduce { get; set; }

        [Dump(false)]
        public object DebugView { get; set; }

        public static void RegisterExpressionMetadatas()
        {
            ClassMetadataResolver.SetClassDumpData(typeof(Expression), typeof(ExpressionMetadata));
            ClassMetadataResolver.SetClassDumpData(typeof(LambdaExpression), typeof(LambdaExpressionMetadata));
            ClassMetadataResolver.SetClassDumpData(typeof(ParameterExpression), typeof(ParameterExpressionMetadata));
            ClassMetadataResolver.SetClassDumpData(typeof(BinaryExpression), typeof(BinaryExpressionMetadata));
            ClassMetadataResolver.SetClassDumpData(typeof(ConstantExpression), typeof(ConstantExpressionMetadata));
        }
    }

    abstract class LambdaExpressionMetadata
    {
        [Dump(0)]
        public object Name { get; set; }

        [Dump(1)]
        public object ReturnType { get; set; }

        [Dump(2)]
        public object Parameters { get; set; }

        [Dump(3)]
        public object Body { get; set; }

        [Dump(int.MinValue)]
        public object TailCall { get; set; }
    }

    [Dump(DefaultProperty="Name")]
    abstract class ParameterExpressionMetadata
    {
        [Dump(0)]
        public object Name { get; set; }

        [Dump(1)]
        public object IsByRef { get; set; }
    }

    abstract class BinaryExpressionMetadata
    {
        [Dump(0)]
        public object Left { get; set; }

        [Dump(1)]
        public object Right { get; set; }

        [Dump(-1)]
        public object Method { get; set; }

        [Dump(-2)]
        public object Conversion { get; set; }

        [Dump(-3)]
        public object IsLifted { get; set; }

        [Dump(-4)]
        public object IsLiftedToNull { get; set; }
    }

    abstract class ConstantExpressionMetadata
    {
        [Dump(0)]
        public object Value { get; set; }
    }
}
